;(function () {
  // 类装饰器

  const doc: ClassDecorator = (target: any) => {
    console.log(target)
    target.prototype.name = 'Animal'
  }

  //使用装饰器 @doc  就可以

  @doc
  class Animal {
    constructor() {}
  }
  /* 
  class Animal{
    constructor() {
       
     }
  }
  doc(Animal)      //这样可以做到向下兼容
  */

  const animal: any = new Animal()
  console.log(animal.name)
})()
;(function () {
  //属性装饰器
  const doc: PropertyDecorator = (target: any, key: string | symbol) => {
    console.log('target', target, 'key', key)
    //target 指向属性所在类的原型对象  key 指向属性
  }


  class Dog {
    @doc
    public name: string
    constructor() {
      this.name = 'dog'
    }
  }
})()
;(function () {
  //方法装饰器
  const doc: MethodDecorator = <T>(target: any, key: string | symbol,descriptor:TypedPropertyDescriptor<T>):TypedPropertyDescriptor<T> | void => {
    console.log('target', target, 'key', key,'descriptor',descriptor)
    //target 指向属性所在类的原型对象  key 指向属性
  }


  class Dog {

    public name: string
    constructor() {
      this.name = 'dog'
    }
    @doc
    getName() {
      
    }
  }
})()
;(function () {
  //参数装饰器
  const doc: ParameterDecorator = (target: any, key: string | symbol,parameterIndex:number)=> {
    console.log('target', target, 'key', key,'parameterIndex',parameterIndex)
    //target 指向属性所在类的原型对象  key 指向属性
    //参数所在位置
  }


  class Dog {

    public name: string
    constructor() {
      this.name = 'dog'
    }

    getName(name:string , @doc age:number) {
      
    }
  }
})()
